﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Data;
using System.IO;
using System.Linq;
using Cinch;
using System.Configuration;
using System.Windows.Threading;


namespace Anata.Client
{
    /// <summary>
    /// </summary>
    public class KaryawanSelectViewModel : ViewModelBase
    {
        #region Data
        #region Data.Primitives
        private String filterKeyword = "";
        private int criteriaSortIdLayanan;

        private bool isAllLoaded = false;
        private int pageLoaded = 0;
        private DispatcherTimer filterTimer;
        #endregion

        #region Data.Rules
        #endregion

        #region Data.VMs
        private DispatcherNotifiedObservableCollection<KaryawanThumbnailViewModel> karyawans;
        private ICollectionView karyawansCV;
        #endregion

        #region Data.Services
        private IViewAwareStatus viewAwareStatusService;
        private IMessageBoxService messageBoxService;
        private IUIVisualizerService uiVisualizerService;
        private IReferenceProvider referenceProvider;
        #endregion

        #endregion


        #region Constructor
        [ImportingConstructor]
        public KaryawanSelectViewModel(
            IMessageBoxService messageBoxService,
            IUIVisualizerService uiVisualizerService,
            IReferenceProvider referenceProvider)
        {
            #region Constructor.SetupServices
            this.messageBoxService = messageBoxService;
            this.uiVisualizerService = uiVisualizerService;
            //this.viewAwareStatusService = viewAwareStatusService;
            this.referenceProvider = referenceProvider;
            //this.viewAwareStatusService.ViewLoaded += ViewAwareStatusService_ViewLoaded;
            #endregion

            #region Constructor.SetupCommands
            //KonsumenNewCommand = new SimpleCommand<Object, Object>(CanExecuteKonsumenNewCommand, ExecuteKonsumenNewCommand);
            //KonsumenRefreshCommand = new SimpleCommand<Object, Object>(CanExecuteKonsumenRefreshCommand, ExecuteKonsumenRefreshCommand);
            KaryawanFilterKeyUpCommand = new SimpleCommand<Object, Object>(CanExecuteKaryawanFilterKeyUpCommand, ExecuteKaryawanFilterKeyUpCommand);
            KaryawanMouseLeftButtonUpCommand = new SimpleCommand<Object, Object>(CanExecuteKaryawanMouseLeftButtonUpCommand, ExecuteKaryawanMouseLeftButtonUpCommand);
            #endregion

            #region Constructor.SetupDataWrappers
            #endregion

            #region Constructor.SetupValidationRules
            #endregion

            #region Constructor.SetupVMs
            Karyawans = new DispatcherNotifiedObservableCollection<KaryawanThumbnailViewModel>();
            KaryawansCV = CollectionViewSource.GetDefaultView(Karyawans);
            #endregion

            Mediator.Instance.Register(this);

            #region Constructor.Filter
            filterTimer = new DispatcherTimer();
            filterTimer.Interval = TimeSpan.FromMilliseconds(
                Int32.Parse(ConfigurationManager.AppSettings["FilterResponsiveness"].ToString()));
            filterTimer.Tick += new EventHandler(LazyFilterCallback);
            #endregion
        }
        #endregion

        #region Public Properties
        #region Public.Commands
        public SimpleCommand<Object, Object> KaryawanFilterKeyUpCommand { get; private set; }
        public SimpleCommand<Object, Object> KaryawanMouseLeftButtonUpCommand { get; private set; }
        #endregion

        #region Public.ViewMode
        #endregion

        #region Public.Data
        /// <summary>
        /// </summary>
        static PropertyChangedEventArgs filterKeywordChangeArgs =
            ObservableHelper.CreateArgs<KaryawanSelectViewModel>(x => x.FilterKeyword);
        public String FilterKeyword
        {
            get { return filterKeyword; }
            set
            {
                filterKeyword = value;
                NotifyPropertyChanged(filterKeywordChangeArgs);
                LazyFilter();
            }
        }
        #endregion

        #region Public.Criteria
        public int CriteriaSortIdLayanan
        {
            get { return criteriaSortIdLayanan; }
            set { criteriaSortIdLayanan = value; }
        }
        #endregion

        #region Public.CachedCollection
        #endregion

        #region Public.DataVMs
        /// <summary>
        /// Loaded Konsumen
        /// </summary>
        static PropertyChangedEventArgs karyawansChangeArgs =
            ObservableHelper.CreateArgs<KaryawanSelectViewModel>(x => x.Karyawans);

        public DispatcherNotifiedObservableCollection<KaryawanThumbnailViewModel> Karyawans
        {
            get { return karyawans; }
            set
            {
                karyawans = value;
                NotifyPropertyChanged(karyawansChangeArgs);
            }
        }
        /// <summary>
        /// Loaded Konsumen
        /// </summary>
        static PropertyChangedEventArgs karyawansCVChangeArgs =
            ObservableHelper.CreateArgs<KaryawanSelectViewModel>(x => x.KaryawansCV);

        public ICollectionView KaryawansCV
        {
            get { return karyawansCV; }
            set
            {
                karyawansCV = value;
                NotifyPropertyChanged(karyawansCVChangeArgs);
            }
        }
        #endregion
        #endregion

        #region Command Handlers
        /// <summary>
        /// </summary>
        private bool CanExecuteKaryawanFilterKeyUpCommand(Object args)
        {
            return true;
        }
        /// <summary>
        /// </summary>
        private void ExecuteKaryawanFilterKeyUpCommand(Object args)
        {
            LazyFilter();
        }

        /// <summary>
        /// </summary>
        private bool CanExecuteKaryawanMouseLeftButtonUpCommand(Object args)
        {
            return true;
        }
        /// <summary>
        /// </summary>
        private void ExecuteKaryawanMouseLeftButtonUpCommand(Object args)
        {
            if (KaryawansCV.CurrentPosition > -1)
            {
                CloseActivePopUpCommand.Execute(true);
            }
        }
        #endregion

        #region IViewStatusAwareInjectionAware Members
        #endregion

        #region Private Methods
        #region PrivateMethods.ViewLoaded
        private void ViewAwareStatusService_ViewLoaded()
        {
            LoadKaryawans();
        }
        #endregion

        #region PrivateMethods.Filter
        private void LazyFilter()
        {
            filterTimer.Stop();
            filterTimer.Start();
            Console.WriteLine("typing");
        }
        private void LazyFilterCallback(object sender, EventArgs e)
        {
            Console.WriteLine("stopped typing, filtering with keyword: " + filterKeyword);
            filterTimer.Stop();
            if (filterKeyword != "")
            {
                KaryawansCV.Filter = new Predicate<object>(LazyFilterPredicate);
            }
            else
            {
                KaryawansCV.Filter = null;
            }
        }
        private bool LazyFilterPredicate(object row)
        {
            KaryawanThumbnailViewModel ktvm = row as KaryawanThumbnailViewModel;
            return (ktvm.Nama.ToLower().Contains(filterKeyword.ToLower()));
        }
        #endregion

        #region PrivateMethods.Loader
        /// <summary>
        /// loader
        /// </summary>
        private void LoadKaryawans()
        {
            referenceProvider.LazyFetchKaryawans(pageLoaded, PostLoadKaryawans);
        }
        #endregion

        #region PrivateMethods.PostLoader
        /// <summary>
        /// post loader
        /// </summary>
        private void PostLoadKaryawans(List<KaryawanThumbnailViewModel> ktvms)
        {
            //rekursif sampai semua diload
            int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
            foreach (var ktvm in ktvms)
            {
                if (IsRelevant(ktvm))
                {
                    Karyawans.Insert(0, ktvm);
                }
                else
                {
                    Karyawans.Add(ktvm);
                }
            }

            if (ktvms.Count != pageSize)
            {
                //basis
                //sudah habis, done loading
                isAllLoaded = true;
            }
            else
            {
                //rekurens
                ++pageLoaded;
                LoadKaryawans();
            }
        }
        #endregion

        #region PrivateMethods.Filter
        #endregion

        #region PrivateMethods.Sorter
        private bool IsRelevant(KaryawanThumbnailViewModel ktvm)
        {
            bool retval = false;
            foreach (var kltvm in ktvm.KaryawanLayanans)
            {
                retval = kltvm.IdLayanan == criteriaSortIdLayanan;
                if (retval)
                    break;
            }
            return retval;
        }
        #endregion
        #endregion

        #region PublicMethods
        #region PublicMethods.LoadStarter
        public void StartLoading()
        {
            LoadKaryawans();
        }
        #endregion
        #endregion
    }
}